package edu.ccut.saturn.component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.json.JSONException;
import org.json.JSONObject;

import edu.ccut.saturn.component.impl.SaturnDataDictTypeInfo;
import edu.ccut.saturn.component.impl.SaturnDictItemInfo;

public class SaturnDictionaryManager extends HashMap<String, Object> {

	private static final long serialVersionUID = 191293021930129L;

	private static final String LOGGER_KEY_BUNDLE_SERVICE = SaturnLoggerManager.LOGGER_KEY_BUNDLE_SERVICE;

	protected static ILogger logger = SaturnLoggerManager.getInstance()
			.getSaturnLogger(LOGGER_KEY_BUNDLE_SERVICE);

	private Map<String, IDataDictTypeInfo> dictInfos;

	private static SaturnDictionaryManager instance;

	static {
		instance = new SaturnDictionaryManager();
	}

	private SaturnDictionaryManager() {
		dictInfos = new HashMap<String, IDataDictTypeInfo>();
	}

	public static SaturnDictionaryManager getInstance() {
		return instance;
	}

	public void addBundleDictInfo(String key, IDataDictTypeInfo dictTypeInfo) {
		logger.debug("add dictionary key \"" + key + "\"");
		this.dictInfos.put(dictTypeInfo.getType(), dictTypeInfo);
	}

	public void removeBundleDictInfo(String key) {
		if (dictInfos.containsKey(key)) {
			this.dictInfos.remove(key);
			logger.debug("remove dictInfo key is : \"" + key + "\"");

			return;
		}
		logger.warn("failed to remove dictInfo, because the key : \"" + key
				+ "\" is not valid");
	}

	public IDataDictTypeInfo getDataDictTypeInfo(String key)
			throws SaturnComponentException {

		IDataDictTypeInfo dataDictTypeInfo = this.dictInfos.get(key);

		if (dataDictTypeInfo == null) {
			throw new SaturnComponentException(
					"Failed to get dict ;The dictionary [" + key
							+ "] does not exist or is validate!");

		}

		return dataDictTypeInfo;
	}

	public IDictItemInfo getDataDictItemInfo(String key, String code)
			throws SaturnComponentException {

		IDictItemInfo dictItemInfo = null;
		IDataDictTypeInfo dataDictTypeInfo = this.dictInfos.get(key);
		List<IDictItemInfo> dictItemList = dataDictTypeInfo.getItems();
		if (dictItemList != null) {
			for (IDictItemInfo itemInfo : dictItemList) {
				String orgcode = itemInfo.getCode();
				if (orgcode.equals(code)) {
					dictItemInfo = itemInfo;
					break;
				}
			}
		}
		if (dictItemInfo == null) {
			throw new SaturnComponentException(
					"Failed to get dictItem ;The dictItem key [" + code
							+ "] does not exist or is validate!");

		}
		return dictItemInfo;
	}

	// public Object get(Object key) {
	// return this.getDictList(key.toString());
	// }
	public Object get(Object key) {
		String keyStr = key.toString();

		if (keyStr.endsWith("_json")) {

			int index = keyStr.indexOf("_json");

			if (index > 0) {
				keyStr = keyStr.substring(0, index);

				JSONObject object = new JSONObject();

				try {
					//
					object.put(keyStr, this.getDictList(keyStr));
					return object.toString();
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		}
		//
		return this.getDictList(keyStr);
	}

	public List<Map<String, String>> getDictListAll(String type) {
		IDataDictTypeInfo dataDictTypeInfo = null;
		try {
			dataDictTypeInfo = getDataDictTypeInfo(type);
		} catch (SaturnComponentException e) {
			e.printStackTrace();
		}

		if (dataDictTypeInfo != null) {
			List<IDictItemInfo> itemList = dataDictTypeInfo.getItems();
			List<Map<String, String>> dictList = new ArrayList<Map<String, String>>(
					itemList.size());

			if (itemList != null) {

				for (IDictItemInfo itemInfo : itemList) {
					Map<String, String> item = new HashMap<String, String>();
					item.put("key", itemInfo.getCode());
					item.put("value", itemInfo.getValue());
					item.put("pinyin", itemInfo.getPinyin());
					item.put("parentcode", itemInfo.getParentCode());
					dictList.add(item);
				}
			}
			return dictList;
		}
		return null;
	}

	public List<Map<String, String>> getDictListWithParentCode(String type,
			String parentCode) {

		IDataDictTypeInfo dataDictTypeInfo = null;
		try {
			dataDictTypeInfo = getDataDictTypeInfo(type);
		} catch (SaturnComponentException e) {
			e.printStackTrace();
		}

		if (dataDictTypeInfo != null) {
			List<IDictItemInfo> itemList = dataDictTypeInfo.getItems();
			List<Map<String, String>> dictList = new ArrayList<Map<String, String>>(
					itemList.size());

			if (itemList != null) {
				for (IDictItemInfo itemInfo : itemList) {
					if (parentCode == null && itemInfo.getParentCode() == null) {
						Map<String, String> item = new HashMap<String, String>();
						item.put("key", itemInfo.getCode());
						item.put("value", itemInfo.getValue());
						item.put("pinyin", itemInfo.getPinyin());
						item.put("parentcode", itemInfo.getParentCode());
						dictList.add(item);
					}
					if (parentCode != null
							&& parentCode.equals(itemInfo.getParentCode())) {
						Map<String, String> item = new HashMap<String, String>();
						item.put("key", itemInfo.getCode());
						item.put("value", itemInfo.getValue());
						item.put("pinyin", itemInfo.getPinyin());
						item.put("parentcode", itemInfo.getParentCode());
						dictList.add(item);
					}
				}
			}
			return dictList;
		}
		return null;
	}

	public List<Map<String, String>> getDictList(String type) {
		String[] types = type.split("\\$");
		int index = type.indexOf("$");
		if (index < 0) {
			return getDictListAll(type);
		} else if (index != type.length() - 1) {
			return getDictListWithParentCode(types[0], types[1]);
		} else {
			return getDictListWithParentCode(types[0], null);
		}

	}

	// TODO:可以添加缓存，提高效率
	public String getDictValue(String key, Object code) {

		if (code != null && !"".equals(code)) {
			IDataDictTypeInfo dataDictTypeInfo = null;
			try {
				dataDictTypeInfo = getDataDictTypeInfo(key);
			} catch (SaturnComponentException e) {
				e.printStackTrace();
			}

			if (dataDictTypeInfo != null) {
				List<IDictItemInfo> itemList = dataDictTypeInfo.getItems();

				if (itemList != null) {
					for (IDictItemInfo itemInfo : itemList) {
						if (code.toString().equals(itemInfo.getCode())) {
							return itemInfo.getValue();
						}
					}
				}
			}
		}
		return null;
	}

	public Map<String, IDataDictTypeInfo> getDictInfos() {
		return this.dictInfos;
	}

	public IDictItemInfo CreateDictItemInfo() {
		return new SaturnDictItemInfo();
	}

	public IDataDictTypeInfo CreatDataDictTypeInfo() {
		return new SaturnDataDictTypeInfo();
	}

	public List<IDataDictTypeInfo> getAllDataDictTypeInfos() {
		List<IDataDictTypeInfo> allDataDict = new ArrayList<IDataDictTypeInfo>();
		Set<String> dataDictKeySet = dictInfos.keySet();

		if (dataDictKeySet != null) {
			for (String dataDictKey : dataDictKeySet) {
				IDataDictTypeInfo dataDictTypeInfo = dictInfos.get(dataDictKey);

				allDataDict.add(dataDictTypeInfo);
			}
		}
		return allDataDict;
	}

	public boolean hasDictType(String key) {
		if (key != null) {
			return this.dictInfos.containsKey(key);
		}
		return false;
	}
}
